home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 061-070 / amok66 / menu / menu.mod < prev    next >
Text File  |  1993-11-04  |  26KB  |  745 lines

  1. (* ------------------------------------------------------------------------
  2.    :Program.      Menu.
  3.    :Contents.     Proceduren zum Erstellen und Abfragen von Menüs.
  4.    :Author.       Klaus Hlawaty.
  5.    :Address.      Waldhof
  6.    :Address.      3579 Schrecksbach
  7.    :History.      v1.0 - 06.Sep.91
  8.    :History.      v1.1 - 20.Nov.91
  9.    :History.      v1.2 - 23.Nov.91: FmtMenu.
  10.    :Copyright.    Freeware.
  11.    :Language.     Oberon.
  12.    :Translator.   OBERON v2.13 / OLink v2.13d
  13.    :Imports.      Speed.
  14.    :Imports.      xDisplay.
  15.    :Imports.      xIntui.
  16.    :Remarks.      Benutzt erweiterte RECORDs und STRUCT's.
  17.    :Remarks.      Erweitert die 'MenuItem'-Struktur von Intuition um eine
  18.    :Remarks.        Kennung. Diese kann zum änderungsunabhängigen Abfrage
  19.    :Remarks.        von Menüpunkten benutzt werden.
  20.    :Remarks.      Erweitert das 'Window'-Record von Display um einige
  21.    :Remarks.        Pointer zum Aufbau und Verwaltung von Menü's.
  22.    :Remarks.        Ein Window muß also mit dem 'WinMenu'-Record und
  23.    :Remarks.        der Procedure 'OpenWinMenu' aus Menu aufgebaut und mit
  24.    :Remarks.        'CloseWinMenu' aus Menu geschlossen werden.
  25.    :Remarks.        Auf das Window können aber alle Display-Proceduren
  26.    :Remarks.        und alle Möglichkeiten von xDisplay angewandt werden
  27.    :Remarks.      Benutzt die MODULE: speed, xDisplay, xIntui.
  28. ------------------------------------------------------------------------ *)
  29. MODULE Menu;
  30.  
  31. IMPORT
  32.       e : Exec,
  33.       D : Display,
  34.      xD : xDisplay,
  35.       g : Graphics,
  36.       i : Intuition,
  37.      xi : xIntui,
  38.      ng : Requests,
  39.           NoGuruRq,
  40.      ol : OberonLib,
  41.           Speed,
  42.     str : Strings,
  43.       s : SYSTEM;
  44.  
  45. TYPE
  46.     MItem*      = STRUCT(MI : i.MenuItem)
  47.                     Kennung* : INTEGER;
  48.                   END (* STRUCT *);
  49.  
  50.     MItemPtr*   = POINTER TO MItem;
  51.  
  52.     WinMenu*    =  RECORD(D.Window)             (* Erweitertes Window *)
  53.                      LastMenu* : i.MenuPtr;     (* Diese Zeiger werden für *)
  54.                      LastItem* : i.MenuItemPtr; (* die ADD-Befehle         *)
  55.                      LastSub*  : i.MenuItemPtr; (* benötigt.               *)
  56.                      Menu*     : i.MenuPtr;
  57.                    END (* WinMenu *);
  58.  
  59.     WinMenuPtr* = POINTER TO WinMenu;
  60.  
  61. VAR
  62.  
  63.  
  64. (* ======================================================================= *)
  65. (* ============= Öffnen und Schliessen von Fenstern für Menü's =========== *)
  66. (* ======================================================================= *)
  67.  
  68. (*------  Open:  ------*)
  69.  
  70. (* $CopyArrays- *)
  71. PROCEDURE OpenWinMenu*(win2:    WinMenuPtr;
  72.                        title:   ARRAY OF CHAR;
  73.                        x,y,w,h: INTEGER;
  74.                        screen:  i.ScreenPtr): BOOLEAN;
  75.  
  76. (* ------------------------------------------------------------------------
  77.   :Input.     win2    : Zeiger auf die erweiterte WindowStructur.
  78.   :Input.     title   : Titel des Windows.
  79.   :Input.     x,y     : Linker oberer Eckpunkt.
  80.   :Input.     w       : Breite des Window's.
  81.   :Input.     h       : Höhe des Window's.
  82.   :Input.     screen  : Öffnen auf screen / NIL => Workbench.
  83.   :Output.    RETURN  : Wenn geöffnet dann TRUE.
  84.   :Semantic.  Öffnet Window, mit erweitertem Windowstructur für "Menu".
  85. ------------------------------------------------------------------------ *)
  86. BEGIN
  87.   win2.LastMenu := NIL;
  88.   win2.LastItem := NIL;
  89.   win2.LastSub  := NIL;
  90.   RETURN xD.OpenWindow(win2,title,x,y,w,h,screen);
  91. END OpenWinMenu;
  92.  
  93. (*-------------------------------  Close:  ------------------------------*)
  94.  
  95. PROCEDURE KillItem(I : i.MenuItemPtr);
  96. (* ------------------------------------------------------------------------
  97.   :Input.     I : MenüItemPointer.
  98.   :Semantic.  Speicherrückgabe von Item's und SubItems.
  99.   :Remarks.   rekursiver Aufruf.
  100. ------------------------------------------------------------------------ *)
  101. BEGIN
  102.   IF(I # NIL)THEN
  103.     KillItem(I.subItem);    (* Kill Subitem's *)
  104.     KillItem(I.nextItem);
  105.     DISPOSE(I);
  106.   END (* I # NIL *);
  107. END KillItem;
  108.  
  109. PROCEDURE KillMenu(m : i.MenuPtr);
  110. (* ------------------------------------------------------------------------
  111.   :Input.     I : Menüpointer.
  112.   :Semantic.  Speicherrückgabe von Menü's.
  113.   :Remarks.   rekursiver Aufruf.
  114. ------------------------------------------------------------------------ *)
  115. BEGIN
  116.   IF(m # NIL)THEN
  117.     KillItem(m.firstItem);
  118.     KillMenu(m.nextMenu);
  119.     DISPOSE(m);
  120.   END (* m # NIL *);
  121. END KillMenu;
  122.  
  123. PROCEDURE Close*(d: D.DispElPtr);
  124. (* ------------------------------------------------------------------------
  125.    :Input.     d  : Zeiger auf D.Screen, D.Window oder WinMenu-Record.
  126.    :Semantic.  Schließt Menü und Window.
  127. ------------------------------------------------------------------------ *)
  128.  
  129. BEGIN
  130.   IF d IS WinMenu THEN
  131.     KillMenu(d(WinMenu).Menu);
  132.   END (* IF d IS WinMenu *);
  133.   D.Close(d);
  134. END Close;
  135.  
  136. (* ======================================================================= *)
  137. (* ================ Proceduren zum Installieren von Menü's =============== *)
  138. (* ======================================================================= *)
  139.  
  140. (* $CopyArrays- *)
  141. PROCEDURE AddMenu*(VAR win      : WinMenuPtr;
  142.                        Text     : ARRAY OF CHAR);
  143. (* ------------------------------------------------------------------------
  144.    :Input.    win       : Zeiger auf das Window.
  145.    :Input.    Text      : Text des Menüs.
  146.    :Output.   win       : Über die WinMenuStruktur wird das Menü angehängt.
  147.    :Semantic. Addiert Menü.
  148. ------------------------------------------------------------------------ *)
  149. VAR
  150.     Menu : i.MenuPtr;
  151.  
  152. BEGIN
  153.   ng.Assert(win # NIL
  154.            ,"AddMenu: Window => NIL, zuerst OpenWinMenu aufrufen");
  155.   NEW(Menu);
  156.     ng.Assert(Menu # NIL, "AddMenu: Kein RAM für Menu");
  157.     xi.FillMenu(Menu,Text,0,0);
  158.     IF(win.LastMenu # NIL)THEN
  159.       win.LastMenu^.nextMenu := Menu;   (* Altes Menu -> Neues *)
  160.     ELSE
  161.       win.Menu               := Menu;
  162.     END (* IF win *);
  163.     win.LastMenu := Menu;
  164.     win.LastItem := NIL;
  165.     win.LastSub  := NIL;
  166. END AddMenu;
  167.  
  168.  
  169. (* $CopyArrays- *)
  170. PROCEDURE AddItem*(win      : WinMenuPtr;
  171.                    Text     : ARRAY OF CHAR;
  172.                    Command  : CHAR;
  173.                    Kennung  : INTEGER
  174.                    )        : i.MenuItemPtr;
  175. (* ------------------------------------------------------------------------
  176.    :Input.    win       : Zeiger auf den Window.
  177.    :Input.    Text      : Text des Menü-Items.
  178.    :Input.    Command   : ShortCut.
  179.    :Input.    Kennung   : Kennung # 0.
  180.    :Output.   win       : Über den WinMenu wird das Item angehängt.
  181.    :Output.   RETURN    : Item Adresse für Änderungen.
  182.    :Semantic. Addiert Item, die Adresse wird für e.v. nachträgliche
  183.    :Semantic. Änderungen zurücküberreicht.
  184.    :Remark.   leftEdge  : Setzen durch FmtMenu.
  185.    :Remark.   topEdge   : Setzen durch FmtMenu.
  186.    :Remark.   width     : Setzen durch FmtMenu.
  187.    :Remark.   height    : Setzen durch FmtMenu.
  188.    :Remark.   MutualEx  : Setzen durch MutualE.
  189.    :Remark.   Flags     : Werden vorbesetzt, Änderung siehe RETURN.
  190. ------------------------------------------------------------------------ *)
  191. VAR
  192.     item  : MItemPtr;
  193.  
  194. BEGIN
  195.   ng.Assert(win # NIL
  196.            ,"AddItem: Window => NIL, zuerst OpenWinMenu aufrufen");
  197.   ng.Assert(win.LastMenu # NIL
  198.            ,"AddItem: LastMenu => NIL, zuerst AddMenu aufrufen");
  199.   NEW(item);
  200.     ng.Assert(item # NIL, "AddItem: Kein RAM für Item");
  201.     xi.FillItem(item,
  202.                 Text,
  203.                 0,
  204.                 0,
  205.                 0,
  206.                 0,
  207.                 SET{i.itemText,i.highComp,i.itemEnabled},
  208.                 LONGSET{},
  209.                 Command);
  210.     item.Kennung := Kennung;
  211.     win.LastSub := NIL;
  212.     IF   (win.LastItem # NIL)THEN
  213.       win.LastItem^.nextItem  := item;
  214.       win.LastItem            := item;
  215.     ELSIF(win.LastMenu # NIL)THEN
  216.       win.LastMenu^.firstItem := item;
  217.       win.LastItem            := item;
  218.     END (* ELSIF *);
  219.   RETURN  item;
  220. END AddItem;
  221. (* $CopyArrays- *)
  222.  
  223. (* $CopyArrays- *)
  224. PROCEDURE AddTItem*(win     : WinMenuPtr;
  225.                    Text     : ARRAY OF CHAR;
  226.                    Command  : CHAR;
  227.                    Kennung  : INTEGER;
  228.                    Checked  : BOOLEAN
  229.                    )        : i.MenuItemPtr;
  230. (* ------------------------------------------------------------------------
  231.    :Input.    win       : Zeiger auf den Window.
  232.    :Input.    Text      : Text des Menü-Items.
  233.    :Input.    Command   : ShortCut.
  234.    :Input.    Kennung   : Kennung # 0.
  235.    :Input.    Checked   : TRUE = aktiviert / FALSE = deaktiviert.
  236.    :Output.   win       : Über den WinMenu wird das Item angehängt.
  237.    :Output.   RETURN    : Item Adresse zur nachträglichen Änderung.
  238.    :Semantic. Addiert Toggle-Item, die Adresse wird für e.v. nachträgliche
  239.    :Semantic. Änderungen zurücküberreicht.
  240.    :Remark.   leftEdge  : Setzen durch FmtMenu.
  241.    :Remark.   topEdge   : Setzen durch FmtMenu.
  242.    :Remark.   width     : Setzen durch FmtMenu.
  243.    :Remark.   height    : Setzen durch FmtMenu.
  244.    :Remark.   MutualEx  : Setzen durch MutualEx oder direkt siehe RETURN.
  245.    :Remark.   Flags     : Werden vorbesetzt, Änderung siehe RETURN.
  246. ------------------------------------------------------------------------ *)
  247. VAR
  248.     item  : i.MenuItemPtr;
  249.  
  250. BEGIN
  251.     item := AddItem(win,Text,Command,Kennung);
  252.     item.flags := item.flags + SET{i.checkIt,i.menuToggle,i.checked};
  253.     IF NOT(Checked) THEN
  254.       EXCL(item.flags,i.checked);
  255.     END (* IF *);
  256.   RETURN item;
  257. END AddTItem;
  258.  
  259. PROCEDURE AddSeparator*(win : WinMenuPtr): i.MenuItemPtr;
  260. (* ------------------------------------------------------------------------
  261.    :Input.    win    : Zeiger auf den Window.
  262.    :Output.   win    : Über den WinMenu wird das Item angehängt.
  263.    :Output.   RETURN : Item Adresse.
  264.    :Semantic. Erzeugt eine Trennlinie im MenÜ.
  265. ------------------------------------------------------------------------ *)
  266. VAR
  267.     Item : i.MenuItemPtr;
  268.     iText : i.IntuiTextPtr;
  269.     Str : e.STRPTR;
  270.  
  271. BEGIN
  272.   Item := AddItem(win
  273.                  ,"-"
  274.                  ,"\o"
  275.                  ,0000); (* Spezifiziert Separator *)
  276.   iText := Item.itemFill;
  277.   Str   := iText.iText;
  278.   Speed.Fill(0,s.SIZE(Str^),Str^,Speed.Byte); (* Löscht String gründlich *)
  279.   Item.flags := SET{i.itemText};
  280.   RETURN Item;
  281. END AddSeparator;
  282.  
  283. (* $CopyArrays- *)
  284. PROCEDURE AddSubI*(win      : WinMenuPtr;
  285.                    Text     : ARRAY OF CHAR;
  286.                    Command  : CHAR;
  287.                    Kennung  : INTEGER
  288.                    )        : i.MenuItemPtr;
  289. (* ------------------------------------------------------------------------
  290.    :Input.    MenuHead  : Zeiger auf den Window.
  291.    :Input.    Text      : Text des Menü-Items.
  292.    :Input.    Command   : ShortCut.
  293.    :Input.    Kennung   : Kennung # 0.
  294.    :Output.   win       : Über den WinMenu wird das Item angehängt.
  295.    :Output.   RETURN    : SubItem Adresse für spätere Änderungen.
  296.    :Semantic. Addiert SubItem, die Adresse wird für e.v. nachträgliche
  297.    :Semantic. Änderungen zurücküberreicht.
  298.    :Remark.   leftEdge  : Setzen durch FmtMenu.
  299.    :Remark.   topEdge   : Setzen durch FmtMenu.
  300.    :Remark.   width     : Setzen durch FmtMenu.
  301.    :Remark.   height    : Setzen durch FmtMenu.
  302.    :Remark.   MutualEx  : Setzen durch MutualEx oder direkt siehe RETURN.
  303.    :Remark.   Flags     : Werden vorbesetzt, Änderung siehe RETURN.
  304. ------------------------------------------------------------------------ *)
  305. VAR
  306.     item  : MItemPtr;
  307.  
  308. BEGIN
  309.   ng.Assert(win # NIL
  310.            ,"AddSubI: Window => NIL, zuerst OpenWinMenu aufrufen");
  311.   ng.Assert(win.LastMenu # NIL
  312.            ,"AddSubI: LastMenu => NIL, zuerst AddMenu aufrufen");
  313.   ng.Assert(win.LastItem # NIL
  314.            ,"AddSubI: LastItem => NIL, zuerst AddItem aufrufen");
  315.   NEW(item);
  316.     ng.Assert(item # NIL, "AddSubI: Kein RAM für SubItem");
  317.     xi.FillItem(item,
  318.                 Text,
  319.                 0,
  320.                 0,
  321.                 0,
  322.                 0,
  323.                 SET{i.itemText,i.highComp,i.itemEnabled},
  324.                 LONGSET{},
  325.                 Command);
  326.     item.Kennung := Kennung;
  327.     IF   (win.LastSub # NIL)THEN
  328.       win.LastSub^.nextItem  := item;
  329.       win.LastSub            := item;
  330.     ELSIF(win.LastItem # NIL)THEN
  331.       win.LastItem^.subItem := item;
  332.       win.LastSub           := item;
  333.     END (* ELSIF *);
  334.   RETURN  item;
  335. END AddSubI;
  336.  
  337. PROCEDURE AddTSubI*(win      : WinMenuPtr;
  338.                     Text     : ARRAY OF CHAR;
  339.                     Command  : CHAR;
  340.                     Kennung  : INTEGER;
  341.                     Checked  : BOOLEAN
  342.                     )        : i.MenuItemPtr;
  343. (* ------------------------------------------------------------------------
  344.    :Input.    win       : Zeiger auf den Window.
  345.    :Input.    Text      : Text des Menü-Items.
  346.    :Input.    Command   : ShortCut.
  347.    :Input.    Kennung   : Kennung # 0.
  348.    :Input.    Checked   : TRUE = aktiviert / FALSE = deaktiviert.
  349.    :Output.   win       : Über den WinMenu wird das Item angehängt.
  350.    :Output.   RETURN    : SubItem Adresse zur nachträglichen Änderung.
  351.    :Semantic. Addiert Toggle-Item, die Adresse wird für e.v. nachträgliche
  352.    :Semantic. Änderungen zurücküberreicht.
  353.    :Remark.   leftEdge  : Setzen durch FmtMenu.
  354.    :Remark.   topEdge   : Setzen durch FmtMenu.
  355.    :Remark.   width     : Setzen durch FmtMenu.
  356.    :Remark.   height    : Setzen durch FmtMenu.
  357.    :Remark.   MutualEx  : Setzen durch MutualEx oder direkt siehe RETURN.
  358.    :Remark.   Flags     : Werden vorbesetzt, Änderung siehe RETURN.
  359. ------------------------------------------------------------------------ *)
  360. VAR
  361.     item  : i.MenuItemPtr;
  362.  
  363. BEGIN
  364.     item := AddSubI(win,Text,Command,Kennung);
  365.     item.flags := item.flags + SET{i.checkIt,i.menuToggle,i.checked};
  366.     IF NOT(Checked) THEN
  367.       EXCL(item.flags,i.checked);
  368.     END (* IF *);
  369.   RETURN item;
  370. END AddTSubI;
  371.  
  372. PROCEDURE AddSubSeparator*(win : WinMenuPtr): i.MenuItemPtr;
  373. (* ------------------------------------------------------------------------
  374.    :Input.    MenuHead  : Zeiger auf den Window.
  375.    :Output.   win       : Über den WinMenu wird das Item angehängt.
  376.    :Output.   RETURN    : Item Adresse.
  377.    :Semantic. Erzeugt eine Trennlinie im Sub-MenÜ.
  378. ------------------------------------------------------------------------ *)
  379. VAR
  380.     Item : i.MenuItemPtr;
  381.     iText : i.IntuiTextPtr;
  382.     Str : e.STRPTR;
  383.  
  384. BEGIN
  385.   Item := AddSubI(win
  386.                  ,"-"
  387.                  ,"\o"
  388.                  ,0000); (* Spezifiziert Separator *)
  389.   iText := Item.itemFill;
  390.   Str   := iText.iText;
  391.   Speed.Fill(0,s.SIZE(Str^),Str^,Speed.Byte); (* Löscht String gründlich *)
  392.   Item.flags := SET{i.itemText};
  393.   RETURN Item;
  394. END AddSubSeparator;
  395.  
  396. (* ======================================================================= *)
  397. (* =================== Proceduren zum Umgang von Menü's ================== *)
  398. (* ======================================================================= *)
  399.  
  400. PROCEDURE KennToItem*(win   : WinMenuPtr;
  401.                       Kenn  : INTEGER) : i.MenuItemPtr;
  402. (* ------------------------------------------------------------------------
  403.    :Input.    win    : Zeiger auf das Window.
  404.    :Input.    Kenn   : Überreicht Kennung.
  405.    :Output.   RETURN : Menuadresse | NIL => Kein Menu.
  406.    :Semantic. Sucht ItemAdresse aus Menu über "Kennung".
  407. ------------------------------------------------------------------------ *)
  408. VAR
  409.     Menu     : i.MenuPtr;
  410.     Item     : i.MenuItemPtr;
  411.     Gefunden : BOOLEAN;
  412.  
  413. BEGIN
  414.   Gefunden := FALSE;
  415.   Menu     := win.Menu;
  416.   WHILE((Menu # NIL)AND NOT(Gefunden))DO
  417.     Item := Menu.firstItem;
  418.     WHILE((Item # NIL)AND NOT(Gefunden))DO
  419.       Gefunden := Item(MItem).Kennung = Kenn;
  420.       IF NOT(Gefunden)THEN Item := Item.nextItem; END;
  421.     END (* WHILE Item *);
  422.     Menu := Menu.nextMenu;
  423.   END (* WHILE Menu *);
  424.   RETURN Item;
  425. END KennToItem;
  426.  
  427. PROCEDURE ItemAdr*(win   : WinMenuPtr;
  428.                    code  : INTEGER) : i.MenuItemPtr;
  429. (* ------------------------------------------------------------------------
  430.    :Input.    win    : Zeiger auf das Window.
  431.    :Input.    code   : Überreicht Messagecode.
  432.    :Output.   RETURN : Menuadresse | NIL => Kein Menu.
  433.    :Semantic. Sucht ItemAdresse aus Menu über "code".
  434.    :Remarks.  Funkioniert auch mit Untermenü's.
  435. ------------------------------------------------------------------------ *)
  436. VAR
  437.     nMenu,
  438.     nItem,
  439.     nSubI : INTEGER;
  440.     Menu  : i.MenuPtr;
  441.     Item  : i.MenuItemPtr;
  442.  
  443. BEGIN
  444.   IF(code # -1)THEN
  445.     xi.decodeMenu(code,nMenu,nItem,nSubI);
  446.       Menu := win.Menu;
  447.       WHILE (nMenu # 0)AND(Menu # NIL) DO
  448.         Menu := Menu.nextMenu;
  449.         DEC(nMenu);
  450.       END (* WHILE *);
  451.       IF(Menu # NIL)THEN
  452.         Item := Menu.firstItem;
  453.         WHILE (nItem # 0)AND(Item # NIL) DO
  454.           Item := Item.nextItem;
  455.           DEC(nItem);
  456.         END (* WHILE *);
  457.         IF(Item # NIL)THEN
  458.           IF(Item.subItem # NIL)THEN
  459.             Item := Item.subItem;
  460.             WHILE nSubI # 0 DO
  461.               Item := Item.nextItem;
  462.               DEC(nSubI);
  463.             END (* WHILE *);
  464.           END (* IF subItem *);
  465.           RETURN Item;
  466.         END (* IF Item # NIL *);
  467.       END   (* IF Menu # NIL *);
  468.   END (* IF code # -1 *);
  469.   RETURN NIL;                                 (* Kein Menu *)
  470. END ItemAdr;
  471.  
  472. PROCEDURE Wait*(    win    : WinMenuPtr;
  473.                 VAR class  : LONGSET;
  474.                 VAR code   : INTEGER;
  475.                 VAR iadr   : s.ADDRESS) : i.MenuItemPtr;
  476. (* ------------------------------------------------------------------------
  477.   :Input.     win    : Zeiger auf das Window.
  478.   :Output.    class  : Überreicht Messageclass zurück.
  479.   :Output.    code   : Überreicht Messagecode  zurück.
  480.   :Output.    iadr   : Überreicht IAddress     zurück.
  481.   :Output.    RETURN : MenuItem-Pointer | NIL => Kein Menü.
  482.   :Semantic.  Wartet auf Intuitionmessage und werte e.v. Menü's aus.
  483. ------------------------------------------------------------------------ *)
  484. VAR
  485.     msg   : i.IntuiMessagePtr;
  486.  
  487. BEGIN
  488.   e.WaitPort(win.window.userPort);
  489.   msg := e.GetMsg(win.window.userPort);
  490.   class := msg.class;
  491.   code  := msg.code;
  492.   iadr  := msg.iAddress;
  493.   e.ReplyMsg(msg);
  494.   IF(i.menuPick IN class)THEN
  495.     RETURN ItemAdr(win,code);
  496.   END;
  497.   RETURN NIL; (* Kein Menü *)
  498. END Wait;
  499.  
  500. PROCEDURE MenuON*  (win : WinMenuPtr);
  501. (* ------------------------------------------------------------------------
  502.    :Input.    win    : Zeiger auf das Window.
  503.    :Semantic. Schaltet Menü ein.
  504. ------------------------------------------------------------------------ *)
  505. BEGIN
  506.   IF(win IS WinMenu)THEN
  507.     ng.Assert(i.SetMenuStrip(win.window,win(WinMenu).Menu^)
  508.                             ,"MenuON: Menü nicht installiert");
  509.   END (* IF win IS WinMenu *);
  510. END MenuON;
  511.  
  512. PROCEDURE MenuOFF* (win : WinMenuPtr);
  513. (* ------------------------------------------------------------------------
  514.    :Input.    win    : Zeiger auf das Window.
  515.    :Semantic. Schaltet Menü aus.
  516. ------------------------------------------------------------------------ *)
  517. BEGIN
  518.   IF(win IS WinMenu)THEN
  519.     IF(win.window.menuStrip # NIL)THEN
  520.       i.ClearMenuStrip(win.window);
  521.     END;
  522.   END (* IF win IS WinMenu *);
  523. END MenuOFF;
  524.  
  525. PROCEDURE ItemON*  (win  : WinMenuPtr;
  526.                     Kenn : INTEGER);
  527. (* ------------------------------------------------------------------------
  528.    :Input.    win  : Zeiger auf das Window.
  529.    :Input.    Kenn : Kennung des anzuschaltenden Item's.
  530.    :Semantic. Schaltet Item ein.
  531.    :Remarks.  Verändert Item.flags.
  532. ------------------------------------------------------------------------ *)
  533. VAR
  534.     Item : i.MenuItemPtr;
  535.  
  536. BEGIN
  537.   IF(win IS WinMenu)THEN
  538.     Item := KennToItem(win,Kenn);
  539.     IF(Item # NIL)THEN
  540.       INCL(Item.flags,i.itemEnabled);
  541.     END (* IF *);
  542.   END (* IF win IS WinMenu *);
  543. END ItemON;
  544.  
  545. PROCEDURE ItemOFF*(win  : WinMenuPtr;
  546.                    Kenn : INTEGER);
  547. (* ------------------------------------------------------------------------
  548.    :Input.    win  : Zeiger auf das Window.
  549.    :Input.    Kenn : Kennung des anzuschaltenden Item's.
  550.    :Semantic. Schaltet Item aus.
  551.    :Remarks.  Verändert Item.flags.
  552. ------------------------------------------------------------------------ *)
  553. VAR
  554.     Item : i.MenuItemPtr;
  555.  
  556. BEGIN
  557.   IF(win IS WinMenu)THEN
  558.     Item := KennToItem(win,Kenn);
  559.     IF(Item # NIL)THEN
  560.       EXCL(Item.flags,i.itemEnabled);
  561.     END (* IF *);
  562.   END (* IF win IS WinMenu *);
  563. END ItemOFF;
  564.  
  565. (* ======================================================================= *)
  566. (* ==================== Formatierung ===================================== *)
  567. (* ======================================================================= *)
  568.  
  569. PROCEDURE SearchBig(    Item : i.MenuItemPtr;
  570.                     VAR B    : INTEGER;
  571.                     VAR Ins  : BOOLEAN     );
  572. (* ------------------------------------------------------------------------
  573.   :Input.     Item : ItemPointer.
  574.   :I/O.       B    : Breite des Textes.
  575.   :I/O.       Ins  : Einfügen zweier Blank's.
  576.   :Semantic.  Sucht rekursiv nach größtem Textbreite.
  577. ------------------------------------------------------------------------ *)
  578. VAR
  579.     iText : i.IntuiTextPtr;
  580.     Str : e.STRPTR;
  581.     B2  : INTEGER;
  582.  
  583. BEGIN
  584.   IF(Item(MItem).Kennung # 0)THEN
  585.     iText := Item.itemFill;
  586.     Str   := iText.iText;
  587.     IF(Ins)AND(Str^[0] # " ")AND(Str^[1] # " ")THEN
  588.       str.Insert(Str^,0,"  ");
  589.     END (* IF checkIt *);
  590.     B2 := str.Length(Str^) * 10;
  591.     IF(i.commSeq IN Item.flags)THEN
  592.       B2 := B2 + 3 * 10;
  593.     END (* IF commSeq *);
  594.     IF(B < B2)THEN B := B2; END;
  595.   END (* IF kein Separator *);
  596.   IF(Item.nextItem # NIL)THEN SearchBig(Item.nextItem,B,Ins); END;
  597. END SearchBig;
  598.  
  599. PROCEDURE SetWert(Item : i.MenuItemPtr;
  600.                   Xb,
  601.                   B,
  602.                   Yb,
  603.                   H    : INTEGER);
  604. (* ------------------------------------------------------------------------
  605.   :I/O.       Item : ItemPointer, Werte werden verändert.
  606.   :Input.     Xb   : Linker Begin des Textes.
  607.   :Input.     B    : Breite des Textes.
  608.   :Input.     Yb   : Oberer Begin des Textes.
  609.   :Input.     H    : Höhe des Textes.
  610.   :Semantic.  Setzte der Werte.
  611. ------------------------------------------------------------------------ *)
  612. VAR
  613.     iText : i.IntuiTextPtr;
  614.     Str : e.STRPTR;
  615.  
  616. BEGIN
  617.   IF(Item(MItem).Kennung = 0)THEN
  618.     iText := Item.itemFill;
  619.     Str   := iText.iText;
  620.     Speed.FillC("-",(B DIV 10)+1,Str^);
  621.   END (* IF Separator *);
  622.   Item.leftEdge := Xb;
  623.   Item.topEdge  := Yb;
  624.   Item.width    := B;
  625.   Item.height   := H;
  626.   Item := Item.nextItem;
  627.   IF(Item # NIL)THEN SetWert(Item,Xb,B,Yb+H,H); END;
  628. END SetWert;
  629.  
  630. PROCEDURE FmtItem(Item : i.MenuItemPtr;
  631.                   Xb   : INTEGER     );
  632.  
  633. (* ------------------------------------------------------------------------
  634.   :I/O.       Item : ItemPointer, Werte werden verändert.
  635.   :Input.     Xb   : Begin des Textes.
  636.   :Semantic.  Formatiert die Itemzeile.
  637. ------------------------------------------------------------------------ *)
  638. VAR
  639.     lfItem : i.MenuItemPtr;
  640.     Xe     : INTEGER;
  641.     Ins    : BOOLEAN;
  642.  
  643. BEGIN
  644.   Ins    := FALSE;
  645.   lfItem := Item;
  646.   WHILE(lfItem # NIL)DO
  647.     Ins := Ins OR (i.checkIt IN lfItem.flags);
  648.     lfItem := lfItem.nextItem;
  649.   END (* WHILE *);
  650.   SearchBig(Item,Xe,Ins);
  651.   SetWert(Item,Xb,Xe,1,10);
  652.   WHILE(Item # NIL)DO
  653.     IF(Item.subItem # NIL)THEN FmtItem(Item.subItem,Xe); END;
  654.     Item := Item.nextItem;
  655.   END (* WHILE *);
  656. END FmtItem;
  657.  
  658. PROCEDURE FmtMenu*(win : WinMenuPtr);
  659. (* ------------------------------------------------------------------------
  660.   :I/O.       win    : Zeiger auf das Window.
  661.   :Output.    Verändert die Inhalte des Menü-Baumes.
  662.   :Semantic.  Formatiert die Menü's.
  663.   :Remarks.   Diese Procedure sollte nach dem Aufbau des Menü's
  664.   :Remarks.   und vor dem Einschalten mit MenuON aufgerufen werden !!!
  665. ------------------------------------------------------------------------ *)
  666. VAR
  667.     Menu : i.MenuPtr;
  668.     Von,
  669.     Len  : INTEGER;
  670.  
  671. BEGIN
  672.   Von := 0;
  673.   Menu := win.Menu;
  674.   WHILE(Menu # NIL)DO
  675.     FmtItem(Menu.firstItem,0);
  676.     Menu.leftEdge := Von;
  677.     Len := str.Length(Menu.menuName^) * 10 + 10;
  678.     Menu.width    := Len;
  679.     Von := Von + Len;
  680.     Menu := Menu.nextMenu;
  681.   END (* While *);
  682. END FmtMenu;
  683.  
  684. (* ======================================================================= *)
  685. (* ===================== MutualExclude =================================== *)
  686. (* ======================================================================= *)
  687.  
  688. PROCEDURE MutualEx*(win   : WinMenuPtr;
  689.                     Kenn1,
  690.                     Kenn2 : INTEGER;
  691.                     Beide : BOOLEAN);
  692. (* ------------------------------------------------------------------------
  693.   :Input.     win   : Zeiger auf das Window.
  694.   :Input.     Kenn1 : diese Kennung schließt
  695.   :Input.     Kenn2 : diese Kennung aus.
  696.   :Input.     Beide : Beide Item's schließen sich gegenseitig aus.
  697.   :Output.    Verändert die Inhalte der beiden Items.
  698.   :Semantic.  Item von Kenn1 schließt Item von Kenn2 (oder beide) aus.
  699.   :Remarks.   Diese Procedure sollte nach dem Aufbau des Itemzweig's
  700.   :Remarks.   aufgerufen werden !!!
  701. ------------------------------------------------------------------------ *)
  702. VAR
  703.     Item,
  704.     Item1,
  705.     Item2 : i.MenuItemPtr;
  706.     Nr,
  707.     Nr1,
  708.     Nr2   : INTEGER;
  709.  
  710. BEGIN
  711.   Item1 := NIL;
  712.   Item2 := NIL;
  713.   ng.Assert(win.LastMenu # NIL
  714.            ,"MutualEx: Menü nicht installiert!");
  715.   IF   (win.LastSub  # NIL)THEN Item := win.LastItem.subItem;
  716.   ELSIF(win.LastItem # NIL)THEN Item := win.LastMenu.firstItem;
  717.                                 Item := NIL;
  718.   END (* Item oder SubItem *);
  719.   Nr := 0;
  720.   WHILE(Item # NIL)DO
  721.     IF(Item(MItem).Kennung = Kenn1)THEN
  722.       Nr1   := Nr;
  723.       Item1 := Item;
  724.     ELSIF(Item(MItem).Kennung = Kenn2)THEN
  725.       Nr2   := Nr;
  726.       Item2 := Item;
  727.     END (* 1. oder 2. Kennung *);
  728.     INC(Nr);
  729.     Item := Item.nextItem;
  730.   END (* WHILE *);
  731.   ng.Assert((Item1 # NIL)AND(Item2 # NIL)
  732.            ,"MutualEx: mindestens eine Kennung nicht gefunden!");
  733.   INCL(Item1.mutualExclude,Nr2);
  734.   IF(Beide)THEN
  735.     INCL(Item2.mutualExclude,Nr1);
  736.   END (* IF Beide *);
  737. END MutualEx;
  738.  
  739. (* ======================================================================= *)
  740. (* ======================================================================= *)
  741. (* ======================================================================= *)
  742.  
  743. END Menu.
  744.  
  745.